/*
* ============================================================================
* 功能描述 ：GPIO模拟I2C功能lcd屏
* 作者       ：ggls
* 创建日期 ：2024.04.24
* ----------------------------------------------------------------------------
* 更新历史 ：
*	日期 　　- 修改者   : 更新内容描述
*
* ============================================================================
*/


#include "main.h"


void LCD_I2C_Start(void) //开始信号
{
	SDA_H;
	SCL_H;
	Delayus(0);
	SDA_L;
}

void LCD_I2C_Stop(void) //停止
{
	SDA_L;
	SCL_H;
	Delayus(0);
	SDA_H;
}

void LCD_send_ACK(char b_ACK)     //主机应答ACK，或不应答
{
	SCL_L;
	Delayus(0);
	if(b_ACK)                    //ACK
	{
		SDA_L;        
	}
	else                          //NOACK
	{
		SDA_H;
	}
	Delayus(0);
	SCL_H;
	Delayus(0);
	SCL_L;
	Delayus(0);
}

void LCD_read_ACK(void)    //等待 24C02 回应 ACK
{
	unsigned char t=0;
	SCL_H;
	Delayus(0);
	while((RA1==1)&&(t<200))t++;    //等待ACK，超时跳出
	SCL_L;
	Delayus(0);
}

void LCD_I2C_init()  //I2C初始化函数，拉高 I2C_SDA 和 I2C_SCL 两条总线
{
	SDA_H;
	SCL_H;
}

void LCD_write_byte(unsigned char date)       //向24C02中写一个字节的数据
{
	unsigned char mask;
	SCL_L;
	for(mask=0x80;mask!=0;mask>>=1)    //从高位到低位依次进行
	{
		
		if((mask&date)==0)
		{
			SDA_L;
		}
		else
		{
			SDA_H;
		}
		Delayus(0);
		SCL_H;
		Delayus(0);
		SCL_L;
	}

}


unsigned char LCD_read_byte()   //读取一字节，从 24C02 中读取一个字节
{
	unsigned char i=0,read_data=0;
	SCL_L;
	Delayus(0);
	SDA_H;
	Delayus(0);
	for(i=0;i<8;i++)
	{
		SCL_H;        //I2C_SCL 拉高准备读数据
		Delayus(0);
		read_data=(read_data<<1)|RA1; //将 I2C_SDA 中的数据读出
		SCL_L;        //I2C_SCL 拉低数据写完毕
		Delayus(0);
	}
	return read_data;
}

void LCD_write_add(unsigned char address,unsigned char date)    //向 24C02 中写一个字节数据
{
	I2C_Start();        //起始信号
	write_byte(0XA0);    //发送写指令
	read_ACK();        //等待应答
	write_byte(address);   //发送要写入的地址
	read_ACK();            //等待应答
	write_byte(date);    //发送数据
	read_ACK();           //等待应答
	I2C_Stop();          //停止信号
}

void LCD_write_MultipleByte(unsigned char address,unsigned char length,unsigned char *date)    //数据块写入
{ 
	I2C_Start();           
	write_byte(0XA0);      
	read_ACK();
	write_byte(address);    
	read_ACK();
	while(length--)
	{
		write_byte(*date++);
		read_ACK();
		Delayus(0);
	}
	I2C_Stop();
}

unsigned char LCD_read_add(unsigned char address,char ACK)  //从 24C02 中读出数据
{
	unsigned char date;
	I2C_Start();          //第一次起始信号
	write_byte(0XA0);      //发送写指令
	read_ACK();              //等待应答
	write_byte(address);     //发送要读取的地址
	read_ACK();              //等待应答
	I2C_Start();            //第二次起始信号
	write_byte(0XA1);       //发送读指令
	read_ACK();              //等待应答
	date=read_byte();      //读数据
	
	send_ACK(ACK);     //主机应答ACK或不应答
	
	I2C_Stop();          //停止信号
	
	return date;
}


void LCD_read_MultipleByte(unsigned char *temp,unsigned char address,unsigned char data_size)    //读出多个数据
{
	I2C_Start();
	write_byte(0XA0);
	read_ACK();
	write_byte(address);
	read_ACK();
	
	I2C_Start();
	write_byte(0XA1);
	read_ACK();
	
	while(data_size--)
	{
		*temp++=read_byte();
		Delayus(0);
		send_ACK(data_size);     //主机应答ACK，当data_size = 0时，发送非应答    主机应答，则继续接受数据；不应答，即表示停止接收
	}
	
	I2C_Stop();
	
	//return temp;
}


